package com.bruce.downloader.download;

import com.bruce.downloader.constant.Constant;
import com.bruce.downloader.print.SimpleDownloadProcessInfo;
import com.bruce.downloader.thread.DownloadProcessInfoThread;
import com.bruce.downloader.util.HttpClientUtils;
import com.bruce.downloader.util.LogUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 抽象下载器
 * <br>CreateDate  2021/09/15 17:11:17
 *
 * @author luotuan
 * @version 1.0.0
 */
public abstract class AbstractDownloader implements IDownloader {
    protected static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
    protected RestTemplate restTemplate;


    public AbstractDownloader(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    /**
     * 下载
     *
     * @param url     url
     * @param dirPath dir路径
     *
     *                <br>CreateDate 2021/09/15 17:11:08
     * @author luotuan
     * @since 1.0.0
     **/
    @Override
    public void download(String url, String dirPath) throws IOException {
        String decodeUrl = URLDecoder.decode(url, "UTF-8");
        HttpEntity<String> httpEntity = new HttpEntity<>(null, new HttpHeaders());
        ResponseEntity<String> responseEntity = restTemplate.exchange(decodeUrl, HttpMethod.HEAD, httpEntity, String.class);
        String fileName = HttpClientUtils.getFileName(decodeUrl, responseEntity.getHeaders());
        String filePath = dirPath + File.separator + fileName;
        File existFile = new File(filePath);
        if(existFile.exists()){
            existFile.delete();
        }
        // 开启下载进度显示定时器任务
        startProcessInfoThread(responseEntity.getHeaders().getContentLength());
        // 开始下载
        LogUtils.info("开始下载文件：{}",fileName);
        long startTime = System.currentTimeMillis();
        doDownload(decodeUrl, dirPath, fileName, responseEntity.getHeaders());
        long endTime = System.currentTimeMillis();
        System.out.println();
        LogUtils.info("下载完成，耗时:{}ms",(endTime-startTime));
    }

    /**
     * 子类实现，做下载动作
     *
     * @param decodeUrl url解码
     * @param dirPath   dir路径
     * @param fileName  文件名称
     * @param headers   头
     *
     *                  <br>CreateDate 2021/09/15 17:10:49
     * @author luotuan
     * @since 1.0.0
     **/
    protected abstract void doDownload(String decodeUrl, String dirPath, String fileName, HttpHeaders headers);

    protected void startProcessInfoThread(long fileSize){
        SimpleDownloadProcessInfo processInfo = new SimpleDownloadProcessInfo().setContentLength(fileSize);
        DownloadProcessInfoThread downloadProcessInfoThread = new DownloadProcessInfoThread(processInfo);
        scheduledExecutorService.scheduleAtFixedRate(downloadProcessInfoThread,1,100, TimeUnit.MILLISECONDS);
    }

    public RestTemplate getRestTemplate() {
        return restTemplate;
    }

    public AbstractDownloader setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
        return this;
    }
}
